import router from '@/router';
import nProgress from 'nprogress';
import 'nprogress/nprogress.css'; // progress bar style
import {getToken} from './utils/auth';
import store from '@/store';
import {ElMessage} from 'element-plus';
import Cookies from 'js-cookie';
import {tokenCookieKey} from "./utils/auth";

nProgress.configure({showSpinner: false});

const whiteList = ['/login']; // 白名单


// https://next.router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards
// https://next.router.vuejs.org/guide/advanced/navigation-guards.html#optional-third-argument-next
// 之前版本的 vue router 是需要调用第三个参数 ---> next   （注意：如果在beforeEach里的参数显示声明了, 则必须使用它, 否则路由渲染会被阻塞, 控制台会报错 ---> [Vue Router warn]: The "next" callback was never called inside of
// 但新版本只用 return 返回对应的值即可:
// + If nothing, undefined or true is returned, the navigation is validated, and the next navigation guard is called.
// + false: cancel the current navigation. If the browser URL was changed (either manually by the user or via back button), it will be reset to that of the from route.
// + A Route Location: Redirect to a different location by passing a route location as if you were calling router.push(), which allows you to pass options like replace: true or name: 'home'. The current navigation is dropped and a new one is created with the same from.
router.beforeEach(async (to/*,from,next*/) => {
  nProgress.start()
  const hasToken = getToken()
  if (hasToken) { // 有token代表已登录
    if (to.path === '/login') {
      nProgress.done()
      return {
        path: '/',
        replace: true
      }
    }else {
      try {
        const hasRoles = store.getters.roles && store.getters.roles.length > 0;
        if (hasRoles) {
          nProgress.done();
          return true;
        }
        // 无用户信息和角色信息 就请求获取
        const roles = await store.dispatch('user/getUserInfo')
        // 该用户未分配角色 进行异常提示
        if (!roles || roles.length === 0) {
          throw new Error('该用户未分配角色');
        }
        // 获取权限路由
        const accessRoutes = await store.dispatch('permission/generateRoutes');
        // 动态注册路由
        accessRoutes.forEach(router.addRoute);

        // 触发重定向
        return to.fullPath;
      }catch (error:any){
        // 移除token重新登录
        await store.dispatch('user/resetToken');
        ElMessage.error('登录失败：' + (error.message || 'Has Error'));
        nProgress.done();
        return `/login?redirect=${to.path}`;
        //todo 也有可能是网络问题, 如果是网络问题, 给出提示即可
      }
    }

  } else {
    if (whiteList.includes(to.path)) {
      nProgress.done()
      return true
    }
    nProgress.done()
    return {
      path: '/login',
      query: {
        redirect: to.path,
        ...to.query
      }
    }
  }
});

router.afterEach(() => {
  nProgress.done()
});
